Ifølge lærerplanen skal dere simulere utfall i […] ulike statistiske fordelinger, dette kan vi gjøre ved hjelp av simuleringer i Python.

Prinsipper for simuleringer

Vi bruker ofte Monte Carlo-simuleringer i programmer for å finne sannsynligheter som er vanskelig å bestemme ved regning. Prinsippet for slike simuleringer er:

  1. Du definerer en hendelse A
  2. Du gjennomfører et stokastisk forsøk N ganger
  3. Du teller antall ganger A inntreffer og kaller denne summen for m
  4. Du beregner sannsynligheten ved: P(A)mN=antall gunstigeantall mulige

Dette er imidlertid ikke den ekte sannsynligheten, men m/N gir en veldig god tilnærming når N er høy. Prøv deg gjerne frem med stadig høyere N (for eksempel 10000, 100 000, 1 000 000 og så videre), men stopp når du merker at programmet tar lang tid å kjøre. Du bør også sjekke at den beregnede sannsynligheten holder seg ganske stabil ved å kjøre programmet flere ganger.

Å trekke fra en statistisk fordeling

Vi kan trekke ut en tilfeldig prøve fra mange ulike statistiske fordelinger. I S2 skal vi fokusere på:

Vi bruker funksjoner fra bibliotekene random og numpy.random for å gjøre uttrekk fra ulike sannsynlighetsfordelinger. Vi skriver import random i toppen av programmene våre for å importere hele random-biblioteket, eller vi kan bruke from random import gauss for å kun importere normalfordelingsfunksjonen.

I alle de følgende eksemplene så vil variabelen tilfeldig_tall inneholde resultatet av et stokastisk forsøk med den respektive sannsynlighetsfordelingen.

Trekke tilfeldig heltall

For å trekke et tilfeldig heltall i intervallet [1,6] (fra og med 1, til og med 6) så kan du bruke random.randint(a,b).

import random
tilfeldig_tall = random.randint(1,6)

Trekke tilfeldig desimaltall

For å trekke et tilfeldig desimaltall i intervallet [0,1 så kan du bruke random.random(). Hvis du trenger å ha et tilfeldig desimaltall i intervallet [5,15 så kan bare gange det tilfeldige tallet med 10 og legge til 5:

import random
tilfeldig_tall = random.random()
tilfeldig_tall2 = 10 * random.random() + 5

Trekke fra normalfordeling

For å trekke et tilfeldig tall fra en normalfordeling med forventningsverdi μ=180 og standardavvik σ=7 så kan du bruke random.gauss(mu, sigma).

import random
tilfeldig_tall = random.gauss(180, 7)

Trekke fra binomisk fordeling

Vi bruker numpy.random.binomial(n, p) for å trekke fra en binomisk fordeling med antall n=n og sannsynlighet for suksess p=p.

For å simulere antallet frø som spirer hvis vi planter 50 frø med sannsynlighet 0,8 for å spire kan vi bruke:

import numpy as np
tilfeldig_tall = np.random.binomial(50, 0.8)

Trekke fra hypergeometrisk fordeling

For å trekke et tilfeldig tall fra en hypergeometrisk fordeling må vi bruke numpy.random.hypergeometric(n_1, n_2, k). Vi importerer biblioteket med import numpy as np også bruker vi funksjonen som vist under med np.random.hypergeometric().

I eksempelet under så har vi 20 fotballspillere (n1=20) og 30 volleyballspillere (n2=30). I vårt stokastiske forsøk så skal vi trekke ut 3 tilfeldige personer (k=3) og telle hvor mange av dem som er fotballspillere (type 1).

import numpy as np
tilfeldig_tall = np.random.hypergeometric(20, 30, 3)

Trekke fra en liste

Vi bruker random.choice(navn_på_liste) for å trekke et tilfeldig element fra en liste.

La oss si at du har kuler med tallene 12,23 og 34 i en bolle. Da kan du trekke en tilfeldig kule med random.choice().

import random
liste = [12, 23, 34]
tilfeldig_tall = random.choice(liste)

Eller la oss si at du har to bananer, ett eple og en ananas i en fruktskål. Da kan du trekke en tilfeldig frukt med random.choice().

import random
liste = ["banan", "banan", "eple", "ananas"]
tilfeldig_frukt = random.choice(liste)

Hvis vi skal trekke 2 frukter uten tilbakelegging så kan vi bruke random.sample(liste, antall).

import random
liste = ["banan", "banan", "eple", "ananas"]
tilfeldige_frukter = random.sample(liste, 2)    // Vi trekker to frukter

Vær oppmerksom på at tilfeldige_frukter i dette tilfellet er en ny liste, slik at den første frukten er lagret i tilfeldige_frukter[0] og den andre frukten er lagret i tilfeldige_frukter[1], den tredje frukten er lagret i tilfeldige_frukter[2] og så videre.

Tips for simuleringer av stokastiske forsøk i S2

Lage en simulering fra stokastisk forsøk

En simulering i S2 bør "alltid" ha med:

  • Antall delforsøk (for eksempel N = 1000)
  • Antall gunstige utfall = 0 (antall_gunstige = 0)
  • En løkke. Som oftest for i in range(N):
  • Inni løkka må vi gjøre en test for å sjekke om vi har et gunstig utfall, for eksempel if (kjoretid < 30):
  • Hvis testen er sann så legger vi til 1 på antall gunstige: antall_gunstige += 1
  • En utregning av den estimerte sannsynligheten ved å ta antall_gunstige / N

Oppgaver

Oppgave 1 – Antall seksere med terning

import random

N = 1000
antall_gunstige = 0

for i in range(N):
	terningkast = random.randint(1, 6)
	if terningkast == 6:
		antall_gunstige += 1
print(f"Vi fikk {antall_gunstige} seksere på {N} terningkast."),  

ssh = antall_gunstige / N
print(f"Sannsynligheten for å få en sekser er omtrent {ssh * 100:.2f} %.")
# {ssh * 100:.2f} tar desimaltallet ssh og multipliserer med 100 for å gjøre 
# det om til prosent sannsynlighet. Deretter viser vi tallet på skjermen
# med 2 desimaler ved å skrive :.2f inni krøllparentesen.

a) Opprett en ny Python-fil og skriv inn programmet ovenfor. Kjør programmet.
b) Hvorfor må antall_gunstige = 0 stå før for-løkka, mens terningkast = randint(1, 6) må stå inni løkka?
c) Gå gjennom programmet linje-for-linje og skriv en kort forklaring på hva som skjer.
d) Gir simuleringen et godt estimat for den sanne sannsynligheten (bør være 16,66… %)? Endre på N slik at du får gode resultater.

Oppgave 2 – Summen av terninger

Bruk simuleringer i Python til å estimere sannsynligheten for:

a) Summen av 2 terningkast er 9 eller mer
b) Summen av 2 terningkast er delelig på 2.

Tips til oppgaven

  • Det er lurt å gjøre to terningkast inne i løkka og lagre resultatene i to ulike variabler, for eksempel terning1 = random.randint(1, 6) og terning2 = random.randint(1, 6)
  • For å sjekke om summen er 9 eller mer kan du gjøre en av følgende sammneligninger
    • if (terning1 + terning2 >= 9):
    • if (terning1 + terning2 > 8):
  • For å sjekke om summen av to terningkast er delelig på 2 så kan vi sjekke om resten etter delingen er null. (25 % 4 gir oss svaret 1, siden 257 gir oss 6 med 1 i rest)
    • if ((terning1 + terning2) % 2 == 0):

Oppgave 3 – Normalfordelt høyde

Vi antar at høyden til menn er normalfordelt med μ=180cm og σ=7cm.

from random import gauss
print(gauss(180, 7))
print(gauss(180, 7))
print(gauss(180, 7))
print(gauss(180, 7))
print(gauss(180, 7))
print(gauss(180, 7))
print(gauss(180, 7))
print(gauss(180, 7))

a) Forklar hva programmet ovenfor gjør.
b) Lag en simulering som beregner sannsynligheten for at en tilfeldig trukket mann er over 189 cm.
c) Lag en simulering som beregner sannsynligheten for at en tilfeldig trukket mann er mellom 170 og 182 cm.

Kombinere sammenligninger i if-setninger

La oss si at vi har høyden til en mann lagret i variabelen hoyde. Da kan vi sjekke om denne er mellom 170 og 182 cm ved å sjekke kombinere to sammenligninger:

if ((hoyde > 170) and (hoyde < 182)):

Siden vi bruker and så må høyden både være over 170 og under 182.

Vi kunne også testet om høyden var over 189 eller under 165 ved å gjøre

if ((hoyde > 189) or (hoyde < 165)):

Oppgave 4 – Ståles kjøretid til jobb

Hvis Ståle kjører til jobb regner han med at kjøretiden er normalfordelt med forventningsverdi 34 minutter og standardavvik 3 minutter. Han har skrevet programmet nedenfor som sier hvor lang tid kjøreturen tar en tilfeldig morgen.

from random import gauss
kjoretid = gauss(34, 3)
print(f"Du bruker {kjoretid} minutter til jobb!")

Ta utgangspunkt i koden ovenfor og bruk simuleringer i Python til å bestemme hvor ofte Ståle bruker mindre enn 30 minutter.

Oppgave 5 – Trekke frukt fra fruktbolle

Ta utgangspunkt i koden under for denne oppgaven. Programmet trekker to frukter fra listen frukter. Du kan justere på N slik at det passer.

import random

N = 1000
antall_gunstige = 0

frukter = ["banan", "banan", "banan", "ananas", "ananas", "eple", "appelsin", "klementin", "klementin"]

for i in range(N):
    tilfeldige_frukter = random.sample(frukter, 2)
Hente ut elementer fra lister

tilfeldige_frukter er en liste med de to fruktene som vi trakk ut. Vi bruker tilfeldige_frukter[0] for å hente ut elementet i posisjon 0 i lista (i Python så er posisjon 0 = det første elementet), og vi kan bruke tilfeldige_frukter[1] for å hente ut det andre elementet.

a) Lag en simulering som beregner sannsynligheten for at de to fruktene du trekker er like.
Bruk en if-setning som sjekker om de to fruktene er like, og deretter øker du antall_gunstige med 1.
b) Lag en simulering som beregner sannsyligheten for å trekke 3 like frukter dersom man trekker 3.
c) Lag en simulering hvor du trekker 3 frukter. Beregn sannsynligheten for at det samlede antallet bokstaver i de tre fruktene er mindre enn 17.

Bruke len for å finne antall bokstaver

Vi kan bruke len til å finne lengden av et objekt.

drikke = "coca-cola"
antall_bokstaver = len(drikke)   # dette gir antall_bokstaver => 9

Vær imidlertid klar over at hvis du gjør len(frukter) så teller len antall elementer i lista frukter og du får svaret 9.

Oppgave 6 – Høyden til 2 år gamle jenter og gutter

Eksamensoppgave fra eksamen høst 2023.

Høyden X til en tilfeldig valgt jente på 24 måneder er tilnærmet normalfordelt med forventningsverdi E(X)=87 cm og standardavvik SD(X)=3,3 cm.

Høyden Y til en tilfeldig valgt gutt på 24 måneder er tilnærmet normalfordelt med forventningsverdi E(Y)=88 cm og standardavvik SD(Y)=3,1 cm.

Lag et program som du kan bruke til å anslå sannsynligheten for at høyden til et tilfeldig valgt barn på 24 måneder er mindre enn 84 cm. Gå ut ifra at det er like mange jenter som gutter i populasjonen.

Hvordan simulere tilfeldig gutt eller jente?

Denne simuleringen bør vi gjøre i to steg:

  1. Først finner vi ut om vi har trukket en gutt eller en jente
  2. Deretter trekker vi fra riktig normalfordeling
tilfeldig_tall = random.randint(1,2)

if tilfeldig_tall == 1:
	# trekker ei tilfeldig jente fra populasjonen
	hoyde = random.gauss(forventning_jente, standardavvik_jente)
else:
	# trekker en tilfeldig gutt fra populasjonen
	hoyde = random.gauss(forventning_gutt, standardavvik_gutt)

Oppgave 7 – Gjennomsnittskarakter fra skoler

Eksamensoppgave fra eksamen vår 2023.

Forskere ønsker å undersøke matematikkunnskapene til elever i videregående skole. Elever fra tre store skoler skal være med i undersøkelsen.

Karakterstatistikk fra de tre skolene viser at karakterene i matematikk er tilnærmet normalfordelt. Tabellen nedenfor viser forventningsverdi og standardavvik for hver av de tre skolene.

Skole Forventningsverdi Standardavvik
Skole A 3,8 1,2
Skole B 3,4 1,4
Skole C 4,1 1,1

Forskerne skal trekke ut 20 elever. For hver elev de skal trekke, trekker de først en tilfeldig skole og deretter en tilfeldig elev fra den skolen.

a) Lag et program som simulerer gjennomsnittskarakteren til 20 elever som er valgt ut på denne måten.
b) Bruk simuleringer til å estimere sannsynligheten for at karaktersnittet til de 20 elevene er høyere enn 4.

Oppgave 8 – Hoppkonkurranse

Tre skihoppere skal delta i en hoppkonkurranse.
Tabellen nedenfor viser forventningsverdi og standardavvik for lengden på et hopp for hver av de tre hopperne. Vi antar at lengden på hoppene er uavhengig og normalfordelt. Alle hopperne hopper ett hopp hver.

Forventningsverdi Standardavvik
Birger 70 meter 20 meter
Maren 80 meter 5 meter
Espen 75 meter 10 meter

Bruk simulering og bestem sannsynligheten for at Maren hopper lengst.

Oppgave 9 – Russens 17. mai-tog

I en by er det tre videregående skoler, som til sammen skal stille med 6 russ som skal bære russefanen i 17. mai-toget.

Skole Antall rødruss Antall blåruss
Skole A 76 23
Skole B 65 2
Skole C 29 52

Russestyret har valgt en litt tungvint måte å velge ut hvem som skal gå i toget. Først skal de trekke en tilfeldig skole, og deretter trekker de 6 tilfeldige russ fra samme skole.

a) Gitt at vi skal trekke 6 tilfeldige russ fra skole A: Forklar hvorfor det vil passe med en hypergeometrisk sannsynlighetsmodell for å bestemme antallet rødruss blant de 6.
b) Bruk simuleringer til å estimere sannsynligheten for at minst 5 av de 6 russene er rødruss.
c) Bruk simuleringer til å estimere sannsynligheten for at alle russene er samme farge.

Oppgave 10 – Antall kast før man får to like terninger på rad

Ane har en vanlig sekssidet terning. Hun ønsker å finne ut hvor mange ganger hun i gjennomsnitt må kaste terningen for å få det samme antallet øyne i to kast på rad.

Bruk simuleringer for å finne dette gjennomsnittet.